#include "pdffile.h"
#include <QDebug>
#include <QMessageBox>
#include "image.h"

PDFFile::PDFFile (QObject *parent) :
    QObject(parent)
{
    m_resolution = 72;
    clear ();
}
//-----------------
PDFFile::~PDFFile()
{
    delete m_doc;
}
//-------------------
void PDFFile::clear()
{
    m_doc = 0 ;
    m_pageCount = 0;
    m_password.clear ();
}
//-----------------------------------------------------------------
bool PDFFile::load (const QString &fileName)
{
    m_doc = Poppler::Document::load (fileName);
    if (! m_doc) {
        clear ();
        return false;
    }

    if (m_doc->isLocked ()) {
        forever {
            delete m_doc;
            PasswordDialog dialog (fileName);

            int result = dialog.exec ();

            if (result == QDialog::Rejected) {
                clear ();
                return false;
            }

            m_doc = Poppler::Document::load (fileName, dialog.password ());
            if (m_doc->isLocked ()) {
                QMessageBox::critical (0,
                                       tr ("Déverrouillage impossible"),
                                       tr ("\nCe document ne peut être déverrouillé \ncar le mot de passe est incorrect. \n"));
            } else {
                m_password = dialog.password ();
                m_pageCount = m_doc->numPages ();
                return true;
            }
        }
    }

    m_password.clear ();
    m_pageCount = m_doc->numPages ();
    return true;
}
//---------------------------------------
QImage PDFFile::pageImage (int pageNum)
{
    if (m_doc == 0) {
        return QImage ();
    }

    --pageNum;
    pageNum = qBound (0, pageNum, m_pageCount - 1);
    m_doc->setRenderHint (Poppler::Document::Antialiasing);
    m_doc->setRenderHint (Poppler::Document::TextAntialiasing);
    m_doc->setRenderHint (Poppler::Document::TextHinting);
    QImage result = m_doc->page (pageNum)->renderToImage (resolution (), resolution ());
    int dpm = Image::dpiToDpm (resolution ());
    result.setDotsPerMeterX (dpm);
    result.setDotsPerMeterY (dpm);
    return result;
}
//----------------------------------------------------------------------------------------------
QString PDFFile::textInRects (const int pageNum,
                              const QVector<QRectF>& selection,
                              const bool usePdfToText,
                              const QString &documentPath)
{
    if (m_doc == 0) return QString ();

    // extraction des rectangles

    int popplerPage = pageNum - 1;
    popplerPage = qBound (0, popplerPage, m_pageCount - 1);

    QString result;
    static const QChar cr ('\n');

    Poppler::Page* page = m_doc->page (popplerPage);
    foreach (const QRectF& rectF, selection) {
        int x = rectF.x () * 72 / resolution ();
        int y = rectF.y () * 72 / resolution ();
        int w = rectF.width () * 72 / resolution ();
        int h = rectF.height () * 72 / resolution ();
        if (! usePdfToText) {
             result += page->text (QRect (x, y, w, h));
        } else {
            QString fileName ("-");
            QString commandLine;
            if (!isLocked ()) {
                commandLine = QString ("pdftotext -f %1 -l %1 -x %2 -y %3 -W %4 -H %5 \"%6\" %7")
                        .arg (pageNum)
                        .arg (x)
                        .arg (y)
                        .arg (w)
                        .arg (h)
                        .arg (documentPath)
                        .arg (fileName);
            } else {
                commandLine = QString ("pdftotext -f %1 -l %1 -x %2 -y %3 -W %4 -H %5 -opw \"%6\" \"%7\" %8")
                        .arg (pageNum)
                        .arg (x)
                        .arg (y)
                        .arg (w)
                        .arg (h)
                        .arg (password ())
                        .arg (documentPath)
                        .arg (fileName);
            }
            result += Config::shell (commandLine);
        }
        result += cr;
    }


    return result;
}
//-------------------------------------------------------------------
bool PDFFile::containsText ()
{
    int popplerPage = 0;
    bool found = false;
    while (!found && popplerPage < m_pageCount) {
        Poppler::Page* page = m_doc->page (popplerPage);
        found = (page->text (QRectF ())).length () > 2;
        delete page;
        ++popplerPage;
    }
    return found;
}
//---------------------------------------------------------
QString PDFFile::textInPages (const int first,
                              const int last,
                              const bool usePdfToText,
                              const QString& documentPath)
{
    if (m_doc == 0) return QString ();

    QString result;

    if (! usePdfToText) {
        const QChar cr ('\n');
        const QChar space (' ');
        const QString endSentence (".?!:");

        for (int popplerPage = first-1 ; popplerPage != last; ++popplerPage) {
            Poppler::Page* page = m_doc->page (popplerPage);

            QList<Poppler::TextBox*> boxList = page->textList ();

            if (boxList.isEmpty ()) continue;

            Poppler::TextBox* box = boxList.at (0);

            bool finished = false;
            do {
                // au début d'une ligne
                bool endOfLine = false;

                do {
                    result += box->text ();
                    boxList.removeAll (box);
                    if (box->hasSpaceAfter ()) {
                        result += space;
                        box = box->nextWord ();
                    } else {
                        endOfLine = true;
                    }
                } while (!endOfLine);

                if (endSentence.contains (result.right (1)))
                    result += cr;
                else
                    result += space;

                if (boxList.isEmpty ()) {
                    finished = true;
                } else {
                    box = boxList.at (0);
                }

            } while (!finished);

            result += cr;
            delete page;
        }

        result.replace ("-\n", "");
        result.replace ("- ", "");
    } else { // utiliser pdftotext
        QString fileName ("-");
        QString commandLine;
        if (m_password.isEmpty ()) {
            commandLine = QString ("pdftotext -f %1 -l %2 \"%3\" %4")
                    .arg (first)
                    .arg (last)
                    .arg (documentPath)
                    .arg (fileName);
        } else {
            commandLine = QString ("pdftotext -f %1 -l %2 -opw \"%3\" \"%4\" %5")
                    .arg (first)
                    .arg (last)
                    .arg (QString (m_password))
                    .arg (documentPath)
                    .arg (fileName);
        }
        result = Config::shell (commandLine);
    }

    return result;
}
